import { BrowserWindow } from 'electron'
import { WeiboLoginData } from '../../shared/types'
import { WEIBO_URLS, LOGIN_WINDOW_CONFIG } from '../../shared/constants'
import { logger } from '@roasmax/logger'
import { BrowserPoolManager } from '@roasmax/browser'
import { rabbitmqManager } from '../core/rabbitmq-manager'
import { useEntityManager } from '../storage/data-source'
import { Account } from '../storage/entities'
import { WeiboLoginUserInfo } from '@roasmax/weibo-types'

export class WeiboLoginManager {
  private loginWindow: BrowserWindow | null = null
  private browserManagerFactory: () => BrowserPoolManager

  constructor(browserManagerFactory: () => BrowserPoolManager) {
    this.browserManagerFactory = browserManagerFactory
  }

  /**
   * 开始微博登录流程
   */
  async startLogin(): Promise<WeiboLoginData> {
    logger.info('开始微博登录流程')

    return new Promise((resolve, reject) => {
      try {
        // 创建登录窗口
        this.createLoginWindow()

        if (!this.loginWindow) {
          throw new Error('无法创建登录窗口')
        }

        // 加载微博登录页面
        this.loginWindow.loadURL(WEIBO_URLS.LOGIN)

        // 监听页面导航事件
        this.loginWindow.webContents.on('did-navigate', async (_, url) => {
          logger.info('页面导航:', { url })

          // 检查是否登录成功（跳转到微博主页）
          if (url.includes('weibo.com') && !url.includes('login')) {
            try {
              const loginData = await this.extractLoginData()
              await useEntityManager(async m => {
                const accountRepo = m.getRepository(Account)
                const accountEntity = Account.fromWeiboLoginData({
                  id: loginData.id,
                  userInfo: loginData.userInfo,
                  cookies: loginData.cookies,
                  isValid: loginData.isValid,
                  lastValidated: loginData.lastValidated,
                  loginMethod: loginData.loginMethod,
                  timestamp: loginData.timestamp
                })
                await accountRepo.save(accountEntity)
              })

              // 关闭登录窗口
              this.closeLoginWindow()

              // 登录成功后 发送 userinfo和cookies到 mq
              try {
                await rabbitmqManager.sendLoginSuccessMessage(loginData)
              } catch (error) {
                logger.warn('发送登录成功消息到MQ失败', error)
              }

              logger.info('微博登录成功', { uid: loginData.userInfo.idstr })
              resolve(loginData)
            } catch (error) {
              logger.error('提取登录数据失败:', error)
              this.closeLoginWindow()
              reject(error)
            }
          }
        })

        // 监听窗口关闭事件
        this.loginWindow.on('closed', () => {
          this.loginWindow = null
          reject(new Error('用户取消登录'))
        })

        // 显示登录窗口
        this.loginWindow.show()

      } catch (error) {
        logger.error('启动登录流程失败:', error)
        reject(error)
      }
    })
  }

  /**
   * 创建登录窗口
   */
  private createLoginWindow(): void {
    if (this.loginWindow && !this.loginWindow.isDestroyed()) {
      this.loginWindow.focus()
      return
    }

    this.loginWindow = new BrowserWindow({
      width: LOGIN_WINDOW_CONFIG.width,
      height: LOGIN_WINDOW_CONFIG.height,
      minWidth: LOGIN_WINDOW_CONFIG.minWidth,
      minHeight: LOGIN_WINDOW_CONFIG.minHeight,
      show: false,
      autoHideMenuBar: true,
      webPreferences: {
        nodeIntegration: false,
        contextIsolation: true,
        webSecurity: true,
        // 使用独立的session避免污染主应用
        partition: `persist:weibo-login-${Date.now()}`
      }
    })

    logger.info('登录窗口已创建')
  }

  /**
   * 提取登录数据
   */
  private async extractLoginData(): Promise<WeiboLoginData> {
    if (!this.loginWindow) {
      throw new Error('登录窗口不存在')
    }

    // 获取cookies
    const cookies = await this.getCookies()

    // 获取用户信息
    const userInfo = await this.getUserInfo()

    const loginData: WeiboLoginData = {
      id: userInfo.id,
      cookies,
      userInfo,
      timestamp: Date.now(),
      isValid: true
    }

    return loginData
  }

  /**
   * 获取重要的cookies
   */
  private async getCookies(): Promise<Electron.Cookie[]> {
    if (!this.loginWindow) {
      throw new Error('登录窗口不存在')
    }

    const loginSession = this.loginWindow.webContents.session
    const allCookies = await loginSession.cookies.get({ domain: '.weibo.com' })

    // 过滤重要的cookies
    const importantCookieNames = ['SUB', 'SUBP', 'SSOLoginState', '_T_WM', 'WBPSESS']
    const importantCookies = allCookies.filter(cookie =>
      importantCookieNames.includes(cookie.name)
    )

    logger.info('获取到重要cookies', { count: importantCookies.length })
    return importantCookies
  }

  /**
   * 获取用户信息
   */
  private async getUserInfo(): Promise<WeiboLoginUserInfo> {
    if (!this.loginWindow) {
      throw new Error('登录窗口不存在')
    }

    try {
      // 执行JavaScript获取用户信息 window.$CONFIG.user
      const userInfo = await this.loginWindow.webContents.executeJavaScript(`
        (function() {
          try {
            // 获取 window.$CONFIG.user
            if (window.$CONFIG && window.$CONFIG.user) {
              return window.$CONFIG.user;
            }

            throw new Error('无法获取用户信息');
          } catch (error) {
            throw new Error('提取用户信息失败: ' + error.message);
          }
        })()
      `)
      logger.info('获取用户信息成功', userInfo)
      // 转换格式
      return userInfo
    } catch (error) {
      logger.error('获取用户信息失败:', error)
      throw error;
    }
  }

  /**
   * 关闭登录窗口
   */
  private closeLoginWindow(): void {
    if (this.loginWindow && !this.loginWindow.isDestroyed()) {
      this.loginWindow.close()
      this.loginWindow = null
    }
  }

  /**
   * 验证会话是否有效
   */
  async validateSession(accountId: string): Promise<{ isValid: boolean; reason?: string; details?: any }> {
    try {
      // 获取账号信息 - 使用数据库ID查找
      const account = await useEntityManager(async m => {
        const accountRepo = m.getRepository(Account)
        return await accountRepo.findOne({ where: { id: parseInt(accountId) } })
      })

      if (!account) {
        logger.error('账号验证失败：账号不存在', { accountId })
        return {
          isValid: false,
          reason: '账号不存在',
          details: { accountId }
        }
      }

      // 使用全局浏览器管理器
      const browserManager = this.browserManagerFactory()
      const sessionId = `validate-${accountId}-${Date.now()}`

      let page
      try {
        // 创建页面
        page = await browserManager.createPage(sessionId)

        // 设置cookies
        const context = page.context()

        // 解析cookies JSON字符串
        const cookies = JSON.parse(account.cookies) as Electron.Cookie[]
        logger.info('开始设置cookies', { totalCookies: cookies.length })

        let successCount = 0
        let skippedCount = 0
        let failedCount = 0

        for (const cookie of cookies) {
          try {
            const cookieData: any = {
              name: cookie.name,
              value: cookie.value,
              domain: cookie.domain || '.weibo.com',
              path: cookie.path || '/',
              secure: cookie.secure || false,
              httpOnly: cookie.httpOnly || false
            }

            // 处理过期时间
            if (cookie.expirationDate && cookie.expirationDate > 0) {
              // 如果过期时间是秒级时间戳，转换为毫秒
              const expirationTime = cookie.expirationDate < 10000000000
                ? cookie.expirationDate * 1000
                : cookie.expirationDate

              // 检查是否已过期
              if (expirationTime > Date.now()) {
                cookieData.expires = Math.floor(expirationTime / 1000) // Playwright 需要秒级时间戳
                logger.debug('Cookie有效期检查通过', {
                  cookieName: cookie.name,
                  expirationDate: new Date(expirationTime).toISOString(),
                  expiresTimestamp: cookieData.expires
                })
              } else {
                logger.warn('Cookie已过期，跳过设置', {
                  cookieName: cookie.name,
                  expirationDate: new Date(expirationTime).toISOString(),
                  currentTime: new Date().toISOString()
                })
                skippedCount++
                continue
              }
            } else {
              logger.debug('Cookie无过期时间，设置为会话cookie', { cookieName: cookie.name })
            }

            await context.addCookies([cookieData])
            logger.debug('Cookie设置成功', {
              cookieName: cookie.name,
              domain: cookieData.domain,
              path: cookieData.path,
              hasExpires: !!cookieData.expires
            })
            successCount++
          } catch (cookieError) {
            logger.warn('设置cookie失败', {
              cookieName: cookie.name,
              error: cookieError,
              cookieData: {
                name: cookie.name,
                domain: cookie.domain,
                expirationDate: cookie.expirationDate
              }
            })
            failedCount++
          }
        }
        // 打开微博主页
        await page.goto('https://weibo.com', { waitUntil: 'domcontentloaded' })

        // 检查 window.$CONFIG.user 是否存在
        const userInfo: WeiboLoginUserInfo = await page.evaluate(() => {
          try {
            // @ts-ignore
            const config = window.$CONFIG
            const user = config?.user
            return user
          } catch (error) {
            return null;
          }
        })

        logger.info('页面状态检查', userInfo)

        // 如果存在用户信息则登录成功
        if (userInfo) {
          const userId = userInfo.idstr
          // 更新账号有效性
          await useEntityManager(async m => {
            const accountRepo = m.getRepository(Account)
            await accountRepo.update(account.id, {
              isValid: true,
              lastValidated: new Date()
            })
          })
          return {
            isValid: true,
            details: userInfo
          }
        } else {
          // 标记账号无效
          await useEntityManager(async m => {
            const accountRepo = m.getRepository(Account)
            await accountRepo.update(account.id, {
              isValid: false,
              lastValidated: new Date()
            })
          })

          return {
            isValid: false,
            reason: '登录已失效，未找到用户信息',
            details: {
              pageInfo: userInfo,
              timestamp: new Date().toISOString(),
              accountId
            }
          }
        }
      } finally {
        // 清理资源
        if (page) {
          await page.close()
        }
        await browserManager.cleanup()
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error)
      const errorStack = error instanceof Error ? error.stack : undefined

      logger.error('账号验证失败：验证过程中发生错误', {
        accountId,
        错误信息: errorMessage,
        错误堆栈: errorStack,
        验证结果: '失败',
        失败原因: '验证过程中发生异常',
        验证时间: new Date().toISOString()
      })

      // 验证失败时标记为无效
      await useEntityManager(async m => {
        const accountRepo = m.getRepository(Account)
        await accountRepo.update(accountId, {
          isValid: false,
          lastValidated: new Date()
        })
      })

      let reason = `验证过程出错: ${errorMessage}`

      // 针对常见错误提供更友好的提示
      if (reason.includes('页面加载超时')) {
        reason += '\n\n可能的解决方案：\n1. 检查网络连接是否稳定\n2. 尝试使用VPN或代理\n3. 稍后重试验证\n4. 检查防火墙设置'
      } else if (reason.includes('网络连接失败')) {
        reason += '\n\n建议检查：\n1. 网络连接状态\n2. DNS设置是否正确\n3. 代理配置是否有效'
      }

      return {
        isValid: false,
        reason,
        details: {
          error: errorMessage,
          timestamp: new Date().toISOString(),
          accountId
        }
      }
    }
  }



  /**
   * 获取存储的账号列表
   */
  async getStoredAccounts(): Promise<WeiboLoginData[]> {
    logger.info('获取存储的账号列表')

    try {
      const accounts = await useEntityManager(async m => {
        const accountRepo = m.getRepository(Account)
        return await accountRepo.find()
      })

      // 转换 AccountEntity 到 WeiboLoginData 格式
      return accounts.map(account => account.toWeiboLoginData())
    } catch (error) {
      logger.error('获取账号列表失败:', error)
      return []
    }
  }
}
